﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Org.BouncyCastle.Asn1;
using System.IO;
using Org.BouncyCastle.Security;


namespace TheClerk.Forms.Templates.raw.Envelope
{
    #region internal Payload
    /// <summary>
    /// The data the Envelope protects for transmission, and its timestamps
    /// </summary>
    /// <remarks>
    /// Payload ::= SEQUENCE {
    ///     content EnvelopeContent,
    ///     postmark Postmarks }
    /// </remarks>
    internal class Payload
    {
        // includes the signatures by the private keys
        internal EnvelopeContent content;
        internal Postmarks postmarks;

        internal Payload()
        {
            content = new EnvelopeContent();
        }

        internal void AddContent(byte[] input)
        {
            content.AddAssertion(new Assertion(new MemoryStream(input.Clone() as byte[])));
        }

        internal void AddAssertion(Assertion content)
        {
            this.content.AddAssertion(content);
        }

        public Stream Serialize()
        {
            // we need this at the top scope
            Stream outputstream = new MemoryStream();

            // 1 serialize the EnvelopeContent
            Stream streamEnvelopeContent = new MemoryStream();
            content.Serialize().CopyTo(streamEnvelopeContent);
            streamEnvelopeContent.Position = 0;

            // 2 generate the Postmarks
            postmarks = new Postmarks(streamEnvelopeContent);
            streamEnvelopeContent.Position = 0;

            // 3 create the sequence
            var dsg = new Org.BouncyCastle.Asn1.DerSequenceGenerator(outputstream);
            dsg.AddObject(content.ToAsn1Encodable());
            dsg.AddObject(postmarks.ToAsn1Encodable());
            dsg.Close();

            outputstream.Seek(0, SeekOrigin.Begin);
            return outputstream;
        }

        public Asn1Encodable toAsn1Encodable()
        {
            return Asn1Object.FromStream(Serialize());
        }

        internal void AddChop(Chop equipment)
        {
            content.AddChop(equipment);

        }

        internal byte[] ToByteArray()
        {
            var s = Serialize();
            var buf = new byte[s.Length];
            s.Read(buf, 0, buf.Length);
            return buf;
        }
    }
    #endregion
}
